﻿using Se.Common;
using Se.Log;
using Se.Model.Host;
using Se.Model.Data;
using Se.Model.GameModel.Character;
using Se.Model.Generator;
using System;
using System.Collections.Generic;
using System.Linq;
using Se.Model.Template.Common;
using Se.Model.Template;

namespace SeServer.Module.Character
{
    /// <summary>
    /// 账户模块
    /// </summary>
    public class AccountController : ModuleControllerBase
    {
        const ControllerType M_TYPE = ControllerType.Account;

        /// <summary>
        /// 账户集合
        /// </summary>
        private MultiKeyDictionary<long, string, Account> m_AccountSet;

        public AccountController()
            : base(M_TYPE)
        {
            this.m_AccountSet = new MultiKeyDictionary<long, string, Account>();
        }

        #region interface ModuleControllerBase

        public override void InitModule()
        {
            DataEntityFactory.TryRegisterEntityCollection(typeof(Account), Se.Data.DBLoadType.MemoryAlways);
        }

        public override void LoadTemplates()
        {
        }

        public override void LoadPlayerData(Player player)
        {

        }

        public override void LoadMemoryData()
        {
            this.LoadAccount();
            SeLog.Info("LoadMemoryData");

        }

        #endregion

        /// <summary>
        /// 加载账户信息
        /// </summary>
        private void LoadAccount()
        {
            this.m_AccountSet = new MultiKeyDictionary<long, string, Account>();
            var accounts = DataEntityFactory.GetEntity<Account>();
            foreach (var account in accounts)
            {
                this.m_AccountSet.Add(account.ID, account.Name, account);
            }
        }

        /// <summary>
        /// 注册账户
        /// </summary>
        /// <param name="session"></param>
        /// <param name="userName"></param>
        /// <param name="pwd"></param>
        /// <param name="asName"></param>
        /// <returns></returns>
        public void RegistAccount(SocketSession session, string userName, string pwd, string asName = "")
        {
            if (session == null) return;
            if (this.m_AccountSet.ContrainSubKey(userName))
            {
                PS_Send.ErrorInfo(session, 1, "此账户已存在");
                return;
            }

            var account = new Account() { Name = userName, Password = pwd, ASName = asName };
            account.Save<Account>();
            this.m_AccountSet.Add(account.ID, account.Name, account);
            PS_Send.RegisterOK(session, account.ID, userName);
            GameGlobalEvent.OnCreateAccount(account);
            
            this.Login(session, userName, pwd);
        }

        /// <summary>
        /// Login
        /// </summary>
        /// <param name="session"></param>
        /// <param name="userName"></param>
        /// <param name="pwd"></param>
        public void Login(SocketSession session, string userName, string pwd)
        {
            if (session == null) return;

            Account account = null;
            if (!this.m_AccountSet.TryGetValue(userName, out account))
            {
                PS_Send.ErrorInfo(session, 1, "用户不存在");
                return;
            }
            if (account.Password != pwd)
            {
                PS_Send.ErrorInfo(session, 1, "密码错误");
                return;
            }
            session.State = SessionState.LoginAccount;
            session.Account = account;
            
            PS_Send.LoginOK(session, account.ID, account.Name, string.Empty);
            
        }

        /// <summary>
        /// 获取账户
        /// </summary>
        /// <param name="session"></param>
        /// <param name="userName"></param>
        /// <param name="pwd"></param>
        /// <returns></returns>
        public Account GetAccount(string userName, string pwd)
        {
            var account = this.GetAccount(userName);
            if (account == null || account.Password != pwd) return null;

            return account;
        }

        /// <summary>
        /// 获取账户
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public Account GetAccount(string userName)
        {
            if (!this.m_AccountSet.ContrainSubKey(userName))
            {
                return null;
            }

            var account = this.m_AccountSet[userName];
            return account;
        }
    }
}
